package com.example.opengldemo.simpleGame.object;

import android.opengl.GLES30;
import android.opengl.GLSurfaceView;
import android.view.View;

import com.example.opengldemo.simpleGame.MatrixState.MatrixState3D;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import static com.example.opengldemo.simpleGame.constant.SourceConstant.ColorCS;

public class LoadedObjectVertexNormalTexture {
    int mProgram;
    int muMVPMatrixHandle;
    int muMMatrixHandle;
    int maPositionHandle;
    int maTexCoorHandle;
    int vCount = 0;
    int mVertexBufferId;
    int mTexCoorBufferId;
    int vaoId = 0;
    int SwitchcolorHandle;

    public LoadedObjectVertexNormalTexture(View mv, float[] vertices, float[] normals, float texCoors[], int programId) {
        this.mProgram = programId;

        initShader();

        initVertexData(vertices, normals, texCoors);
    }


    public void initVertexData(float[] vertices, float[] normals, float texCoors[]) {

        int[] buffIds = new int[2];

        GLES30.glGenBuffers(2, buffIds, 0);

        mVertexBufferId = buffIds[0];

        mTexCoorBufferId = buffIds[1];


        vCount = vertices.length / 3;


        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
        vbb.order(ByteOrder.nativeOrder());
        FloatBuffer mVertexBuffer = vbb.asFloatBuffer();
        mVertexBuffer.put(vertices);
        mVertexBuffer.position(0);

        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVertexBufferId);

        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, vertices.length * 4, mVertexBuffer, GLES30.GL_STATIC_DRAW);

        ByteBuffer tbb = ByteBuffer.allocateDirect(texCoors.length * 4);
        tbb.order(ByteOrder.nativeOrder());
        FloatBuffer mTexCoorBuffer = tbb.asFloatBuffer();
        mTexCoorBuffer.put(texCoors);
        mTexCoorBuffer.position(0);

        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mTexCoorBufferId);

        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, texCoors.length * 4, mTexCoorBuffer, GLES30.GL_STATIC_DRAW);

        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
        initVAO();
    }

    public void initVAO() {
        int[] vaoIds = new int[1];

        GLES30.glGenVertexArrays(1, vaoIds, 0);
        vaoId = vaoIds[0];

        GLES30.glBindVertexArray(vaoId);


        GLES30.glEnableVertexAttribArray(maPositionHandle);
        GLES30.glEnableVertexAttribArray(maTexCoorHandle);

        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVertexBufferId);

        GLES30.glVertexAttribPointer
                (
                        maPositionHandle,
                        3,
                        GLES30.GL_FLOAT,
                        false,
                        3 * 4,
                        0
                );

        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mTexCoorBufferId);

        GLES30.glVertexAttribPointer
                (
                        maTexCoorHandle,
                        2,
                        GLES30.GL_FLOAT,
                        false,
                        2 * 4,
                        0
                );

        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
        GLES30.glBindVertexArray(0);
    }


    public void initShader() {

        maPositionHandle = GLES30.glGetAttribLocation(mProgram, "aPosition");

        maTexCoorHandle = GLES30.glGetAttribLocation(mProgram, "aTexCoor");

        muMVPMatrixHandle = GLES30.glGetUniformLocation(mProgram, "uMVPMatrix");

        muMMatrixHandle = GLES30.glGetUniformLocation(mProgram, "uMMatrix");

        SwitchcolorHandle = GLES30.glGetUniformLocation(mProgram, "ColorCS");

    }

    public void drawSelf(int texId) {

        GLES30.glUseProgram(mProgram);

        GLES30.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState3D.getFinalMatrix(), 0);

        GLES30.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState3D.getMMatrix(), 0);
        GLES30.glUniform1f(SwitchcolorHandle, ColorCS);
        GLES30.glBindVertexArray(vaoId);



        GLES30.glActiveTexture(GLES30.GL_TEXTURE0);
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, texId);

        GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, vCount);
        GLES30.glBindVertexArray(0);

    }
}
